package main;

import entity.*;

import javax.swing.*;  // 导入Swing GUI组件
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;


public class Main {
    // 程序入口点
    public static void main(String[] args) {
        // 创建游戏主窗口
        JFrame frame = new JFrame("飞机大战");
        // 设置窗口大小为400x600像素
        frame.setSize(400, 600);
        // 设置窗口关闭操作，点击关闭按钮时退出程序
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // 设置窗口居中显示
        frame.setLocationRelativeTo(null);
        
        // 创建游戏面板实例
        GamePanel panel = new GamePanel();
        // 将游戏面板添加到窗口中
        frame.add(panel);
        
        // 设置窗口可见，显示游戏界面
        frame.setVisible(true);
    }

    // 游戏面板类，继承自JPanel
    static class GamePanel extends JPanel {
        // 背景图片对象
        private Image backgroundImg;
        // 玩家飞机图片对象
        private Image playerImg;
        // 敌机图片对象
        private Image enemyImg;
        // 玩家飞机
        private Player player;

        // 敌机列表
        private List<Enemy> enemies = new ArrayList<>();
        
        // 敌机子弹列表
        private List<Bullet> enemyBullets = new ArrayList<>();
        
        // 玩家子弹列表
        private List<Bullet> playerBullets = new ArrayList<>();
        
        // 道具列表（仅保留生命道具）
        private List<Prop> props = new ArrayList<>();
        
        // 爆炸效果列表
        private List<Explosion> explosions = new ArrayList<>();

        // 随机数生成器，用于生成敌机
        private Random random = new Random();


        // 面板宽度和高度的默认值
        private int panelWidth = 400;
        private int panelHeight = 600;
        
        // 游戏是否结束
        private boolean gameOver = false;
        // 游戏是否暂停
        private boolean gamePaused = false;
        
        // 玩家飞机图片
        private Image me1Img; // 向前飞行图片
        private Image me2Img; // 左右或停止时的图片
        
        // 子弹图片
        private Image bulletImg;
        private Image bullet1Img;
        private Image bullet2Img;
        
        // 敌机图片
        private Image enemy1Img;
        private Image enemy2Img;
        private Image enemy3Img;
        
        // 爆炸图片
        private List<Image> explosion1Frames = new ArrayList<>();
        private List<Image> explosion2Frames = new ArrayList<>();
        private List<Image> explosion3Frames = new ArrayList<>();
        
        // 道具图片（仅保留生命道具）
        private Image lifePropImg;
        
        // 游戏分数
        private int score = 0;
        
        // 游戏等级
        private int level = 1;
        
        // 玩家射击间隔计数器
        private int shootCooldown = 0;
        private int shootCooldownMax = 10; // 10帧射击一次
        
        // 玩家死亡动画相关
        private Image meDestroy3Img;
        private Image meDestroy4Img;
        private Image gameoverImg;
        private boolean showGameOverImage = false;
        private long gameOverStartTime = 0;
        
        // 按键状态跟踪
        private boolean upPressed = false;
        private boolean downPressed = false;
        private boolean leftPressed = false;
        private boolean rightPressed = false;
        
        // 暂停按钮相关
        private Image pauseImg;
        private Image resumeImg;
        private Rectangle pauseButtonRect;
        private Rectangle resumeButtonRect;

        // 构造函数
        public GamePanel() {
            // 设置面板的首选大小
            setPreferredSize(new Dimension(panelWidth, panelHeight));

            // 加载游戏所需图片资源
            loadImages();

            // 初始化玩家到面板底部中央位置
            int playerX = (panelWidth - 50) / 2; // 飞机宽度约为50像素
            int playerY = 500; // 距离顶部500像素（根据项目规范）
            player = new Player(playerX, playerY, me2Img); // 默认使用me2图片（停止状态）
            
            // 初始化按钮区域
            if (pauseImg != null) {
                pauseButtonRect = new Rectangle(10, 10, pauseImg.getWidth(this), pauseImg.getHeight(this));
            }
            if (resumeImg != null) {
                int resumeX = (panelWidth - resumeImg.getWidth(this)) / 2;
                int resumeY = (panelHeight - resumeImg.getHeight(this)) / 2;
                resumeButtonRect = new Rectangle(resumeX, resumeY, resumeImg.getWidth(this), resumeImg.getHeight(this));
            }

            // 设置面板可以获得焦点，以便接收键盘事件
            setFocusable(true);
            // 确保面板能够接收键盘事件
            requestFocusInWindow();

            // 启动游戏循环线程
            startGameLoop();

            // 添加键盘监听器处理玩家输入
            addKeyListener(new KeyAdapter() {
                // 重写按键按下事件处理方法
                @Override
                public void keyPressed(KeyEvent e) {
                    // 设置按键状态
                    setKeyState(e.getKeyCode(), true);
                }
                
                // 重写按键释放事件处理方法
                @Override
                public void keyReleased(KeyEvent e) {
                    // 重置按键状态
                    setKeyState(e.getKeyCode(), false);
                }
            });
            
            // 添加鼠标监听器处理按钮点击
            addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    handleMouseClick(e);
                }
            });

        }
        
        // 设置按键状态的方法
        private void setKeyState(int keyCode, boolean pressed) {
            switch (keyCode) {
                case KeyEvent.VK_UP:
                    upPressed = pressed;
                    break;
                case KeyEvent.VK_DOWN:
                    downPressed = pressed;
                    break;
                case KeyEvent.VK_LEFT:
                    leftPressed = pressed;
                    break;
                case KeyEvent.VK_RIGHT:
                    rightPressed = pressed;
                    break;
                case KeyEvent.VK_SPACE:
                    if (pressed) { // 只在按下时触发，防止重复发射
                        System.out.println("按下空格键"); // 调试信息
                        firePlayerBullets();
                    }
                    break;
            }
        }

        // 加载游戏图片资源的方法
        private void loadImages() {
            try {
                // 使用类加载器从resources目录加载背景图片
                backgroundImg = new ImageIcon(getClass().getClassLoader().getResource("images/background.png")).getImage();
                // 使用类加载器从resources目录加载玩家飞机图片
                me1Img = new ImageIcon(getClass().getClassLoader().getResource("images/me1.png")).getImage();
                me2Img = new ImageIcon(getClass().getClassLoader().getResource("images/me2.png")).getImage();
                // 使用类加载器从resources目录加载敌机图片
                enemyImg = new ImageIcon(getClass().getClassLoader().getResource("images/enemy.png")).getImage();
                enemy1Img = new ImageIcon(getClass().getClassLoader().getResource("images/enemy1.png")).getImage();
                enemy2Img = new ImageIcon(getClass().getClassLoader().getResource("images/enemy2.png")).getImage();
                enemy3Img = new ImageIcon(getClass().getClassLoader().getResource("images/enemy3_n1.png")).getImage();
                // 使用类加载器从resources目录加载子弹图片
                bulletImg = new ImageIcon(getClass().getClassLoader().getResource("images/bullet.png")).getImage();
                bullet1Img = new ImageIcon(getClass().getClassLoader().getResource("images/bullet1.png")).getImage();
                bullet2Img = new ImageIcon(getClass().getClassLoader().getResource("images/bullet2.png")).getImage();
                
                // 加载爆炸动画帧
                explosion1Frames.add(new ImageIcon(getClass().getClassLoader().getResource("images/enemy1_down1.png")).getImage());
                explosion1Frames.add(new ImageIcon(getClass().getClassLoader().getResource("images/enemy1_down2.png")).getImage());
                explosion1Frames.add(new ImageIcon(getClass().getClassLoader().getResource("images/enemy1_down3.png")).getImage());
                explosion1Frames.add(new ImageIcon(getClass().getClassLoader().getResource("images/enemy1_down4.png")).getImage());
                
                explosion2Frames.add(new ImageIcon(getClass().getClassLoader().getResource("images/enemy2_down1.png")).getImage());
                explosion2Frames.add(new ImageIcon(getClass().getClassLoader().getResource("images/enemy2_down2.png")).getImage());
                explosion2Frames.add(new ImageIcon(getClass().getClassLoader().getResource("images/enemy2_down3.png")).getImage());
                explosion2Frames.add(new ImageIcon(getClass().getClassLoader().getResource("images/enemy2_down4.png")).getImage());
                
                explosion3Frames.add(new ImageIcon(getClass().getClassLoader().getResource("images/enemy3_down1.png")).getImage());
                explosion3Frames.add(new ImageIcon(getClass().getClassLoader().getResource("images/enemy3_down2.png")).getImage());
                explosion3Frames.add(new ImageIcon(getClass().getClassLoader().getResource("images/enemy3_down3.png")).getImage());
                explosion3Frames.add(new ImageIcon(getClass().getClassLoader().getResource("images/enemy3_down4.png")).getImage());
                explosion3Frames.add(new ImageIcon(getClass().getClassLoader().getResource("images/enemy3_down5.png")).getImage());
                explosion3Frames.add(new ImageIcon(getClass().getClassLoader().getResource("images/enemy3_down6.png")).getImage());
                
                // 加载道具图片（仅保留生命道具）
                lifePropImg = new ImageIcon(getClass().getClassLoader().getResource("images/life.png")).getImage();
                
                // 加载玩家死亡动画图片
                meDestroy3Img = new ImageIcon(getClass().getClassLoader().getResource("images/me_destroy_3.png")).getImage();
                meDestroy4Img = new ImageIcon(getClass().getClassLoader().getResource("images/me_destroy_4.png")).getImage();
                gameoverImg = new ImageIcon(getClass().getClassLoader().getResource("images/gameover.png")).getImage();
                
                // 加载暂停和恢复按钮图片
                pauseImg = new ImageIcon(getClass().getClassLoader().getResource("images/pause_nor.png")).getImage();
                resumeImg = new ImageIcon(getClass().getClassLoader().getResource("images/resume_nor.png")).getImage();
            } catch (Exception e) {
                // 如果图片加载失败，输出错误信息
                System.out.println("图片加载失败: " + e.getMessage());
                e.printStackTrace();
            }
        }

        // 启动游戏循环
        private void startGameLoop() {
            // 创建并启动一个新的线程用于游戏循环
            Thread gameThread = new Thread(() -> {
                while (true) {
                    // 处理玩家移动
                    movePlayer();
                    
                    // 更新游戏状态
                    updateGame();
                    // 重绘游戏画面
                    repaint();
                    // 控制游戏循环速度（从50ms减少到20ms以获得更流畅的效果）
                    try {
                        Thread.sleep(20);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
            gameThread.start();

            // 创建并启动敌机生成线程
            Thread enemyThread = new Thread(() -> {
                while (true) {
                    // 随机生成敌机
                    generateEnemy();
                    // 控制敌机生成速度
                    try {
                        Thread.sleep(1000 + random.nextInt(2000));
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
            enemyThread.start();
            
            // 创建并启动敌机子弹发射线程
            Thread bulletThread = new Thread(() -> {
                while (true) {
                    // 随机发射子弹
                    fireEnemyBullets();
                    // 控制子弹发射速度
                    try {
                        Thread.sleep(1500 + random.nextInt(1000));
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
            bulletThread.start();
        }

        // 更新游戏状态
        private void updateGame() {
            // 如果游戏暂停或结束且游戏结束画面已经显示一段时间，不再更新游戏状态
            if (gamePaused || (gameOver && showGameOverImage && System.currentTimeMillis() - gameOverStartTime > 3000)) {
                return;
            }
            
            // 更新玩家
            player.isOutOfBounds(getWidth(), getHeight());
            
            // 处理玩家死亡动画
            if (!player.isAlive()) {
                // 如果玩家刚死亡，记录死亡时间
                if (gameOverStartTime == 0) {
                    gameOverStartTime = System.currentTimeMillis();
                    gameOver = true;
                }
                
                long timeSinceDeath = System.currentTimeMillis() - gameOverStartTime;
                if (timeSinceDeath < 1000) {
                    player.setImage(meDestroy3Img);
                } else if (timeSinceDeath < 2000) {
                    player.setImage(meDestroy4Img);
                } else {
                    showGameOverImage = true;
                }
            }
            
            // 更新所有敌机位置
            for (int i = enemies.size() - 1; i >= 0; i--) {
                Enemy enemy = enemies.get(i);
                enemy.move();
                // 移除飞出屏幕的敌机
                if (enemy.isOutOfBounds(getWidth(), getHeight())) {
                    enemies.remove(i);
                }
            }
            
            // 更新所有子弹位置
            // 更新敌机子弹
            for (int i = enemyBullets.size() - 1; i >= 0; i--) {
                Bullet bullet = enemyBullets.get(i);
                bullet.move();
                // 移除飞出屏幕的子弹
                if (bullet.isOutOfBounds(getWidth(), getHeight())) {
                    enemyBullets.remove(i);
                }
            }
            
            // 更新玩家子弹
            for (int i = playerBullets.size() - 1; i >= 0; i--) {
                Bullet bullet = playerBullets.get(i);
                bullet.move();
                // 移除飞出屏幕的子弹
                if (bullet.isOutOfBounds(getWidth(), getHeight())) {
                    playerBullets.remove(i);
                }
            }
            
            // 更新道具
            for (int i = props.size() - 1; i >= 0; i--) {
                Prop prop = props.get(i);
                prop.move();
                // 移除飞出屏幕的道具
                if (prop.isOutOfBounds(getWidth(), getHeight())) {
                    props.remove(i);
                }
            }
            
            // 更新爆炸效果
            for (int i = explosions.size() - 1; i >= 0; i--) {
                Explosion explosion = explosions.get(i);
                explosion.update();
                // 移除播放完毕的爆炸效果
                if (explosion.isFinished()) {
                    explosions.remove(i);
                }
            }
            
            // 更新射击冷却
            if (shootCooldown > 0) {
                shootCooldown--;
            }
            
            // 检查碰撞
            checkCollisions();
            
            // 更新游戏等级
            updateLevel();
        }
        
        // 更新游戏等级
        private void updateLevel() {
            level = score / 100 + 1;
        }
        
        // 检查碰撞
        private void checkCollisions() {
            // 如果游戏暂停，不再检查碰撞
            if (gamePaused) {
                return;
            }
            
            // 检查玩家子弹与敌机的碰撞
            for (int i = playerBullets.size() - 1; i >= 0; i--) {
                Bullet bullet = playerBullets.get(i);
                for (int j = enemies.size() - 1; j >= 0; j--) {
                    Enemy enemy = enemies.get(j);
                    if (bullet.getRectangle().intersects(enemy.getRectangle())) {
                        // 子弹击中敌机
                        enemy.takeDamage(1);
                        bullet.setAlive(false);
                        
                        // 如果敌机被击毁
                        if (!enemy.isAlive()) {
                            // 添加分数
                            score += enemy.getScore();
                            
                            // 添加爆炸效果
                            List<Image> frames = explosion1Frames;
                            if (enemy instanceof MediumEnemy) {
                                frames = explosion2Frames;
                            } else if (enemy instanceof LargeEnemy) {
                                frames = explosion3Frames;
                            }
                            explosions.add(new Explosion(enemy.getX(), enemy.getY(), frames));
                            
                            // 有一定概率掉落道具
                            if (random.nextInt(100) < 20) { // 20%概率掉落道具
                                // 只掉落生命道具
                                props.add(new LifeProp(enemy.getX(), enemy.getY(), lifePropImg));
                            }
                            
                            enemies.remove(j);
                        }
                        
                        playerBullets.remove(i);
                        break;
                    }
                }
            }
            
            // 检查玩家与敌机的碰撞
            for (int i = enemies.size() - 1; i >= 0; i--) {
                Enemy enemy = enemies.get(i);
                if (player.getRectangle().intersects(enemy.getRectangle())) {
                    // 玩家与敌机碰撞
                    player.takeDamage(30);
                    enemy.takeDamage(enemy.getHealth()); // 敌机也销毁
                    
                    // 添加爆炸效果
                    List<Image> frames = explosion1Frames;
                    if (enemy instanceof MediumEnemy) {
                        frames = explosion2Frames;
                    } else if (enemy instanceof LargeEnemy) {
                        frames = explosion3Frames;
                    }
                    explosions.add(new Explosion(enemy.getX(), enemy.getY(), frames));
                    
                    enemies.remove(i);
                    
                    // 检查游戏是否结束
                    if (!player.isAlive()) {
                        gameOver = true;
                    }
                }
            }
            
            // 检查玩家与敌机子弹的碰撞
            for (int i = enemyBullets.size() - 1; i >= 0; i--) {
                Bullet bullet = enemyBullets.get(i);
                if (player.getRectangle().intersects(bullet.getRectangle())) {
                    // 玩家被子弹击中
                    player.takeDamage(10);
                    enemyBullets.remove(i);
                    
                    // 检查游戏是否结束
                    if (!player.isAlive()) {
                        gameOver = true;
                    }
                }
            }
            
            // 检查玩家与道具的碰撞
            for (int i = props.size() - 1; i >= 0; i--) {
                Prop prop = props.get(i);
                if (player.getRectangle().intersects(prop.getRectangle())) {
                    // 玩家获得道具
                    if (prop instanceof LifeProp) {
                        player.heal(20);
                    }
                    props.remove(i);
                }
            }
        }

        // 生成新的敌机
        private void generateEnemy() {
            // 如果游戏结束或暂停，不再生成敌机
            if (gameOver || gamePaused) {
                return;
            }
            
            int maxWidth = getWidth() - 50;
            int x = (maxWidth > 0) ? random.nextInt(maxWidth) : 0;
            
            // 根据等级生成不同类型的敌机
            int enemyType = random.nextInt(100);
            if (enemyType < 70) {
                // 70%概率生成小型敌机
                enemies.add(new SmallEnemy(x, -50, enemy1Img));
            } else if (enemyType < 90) {
                // 20%概率生成中型敌机
                enemies.add(new MediumEnemy(x, -50, enemy2Img));
            } else {
                // 10%概率生成大型敌机
                enemies.add(new LargeEnemy(x, -100, enemy3Img));
            }
        }
        
        // 敌机发射子弹
        private void fireEnemyBullets() {
            // 如果游戏结束或暂停，不再发射子弹
            if (gameOver || gamePaused) {
                return;
            }
            
            // 随机选择一个敌机发射子弹
            if (!enemies.isEmpty()) {
                int index = random.nextInt(enemies.size());
                Enemy enemy = enemies.get(index);
                // 在敌机正前方发射子弹
                enemyBullets.add(enemy.shoot(bullet1Img));
            }
        }
        
        // 玩家发射子弹
        private void firePlayerBullets() {
            System.out.println("尝试发射子弹"); // 调试信息
            // 如果游戏结束、暂停或冷却中，不能发射子弹
            if (gameOver || gamePaused || shootCooldown > 0) {
                if (gameOver) System.out.println("游戏已结束，无法发射子弹");
                if (gamePaused) System.out.println("游戏已暂停，无法发射子弹");
                if (shootCooldown > 0) System.out.println("射击冷却中: " + shootCooldown);
                return;
            }
            
            System.out.println("发射子弹"); // 调试信息
            // 发射子弹
            playerBullets.add(player.shoot(bulletImg));
            shootCooldown = shootCooldownMax;
        }

        // 处理鼠标点击事件
        private void handleMouseClick(MouseEvent e) {
            int x = e.getX();
            int y = e.getY();
            
            // 检查是否点击了暂停按钮
            if (pauseButtonRect != null && pauseButtonRect.contains(x, y) && !gameOver) {
                gamePaused = true;
                repaint();
                return;
            }
            
            // 检查是否点击了恢复按钮
            if (resumeButtonRect != null && resumeButtonRect.contains(x, y) && gamePaused) {
                gamePaused = false;
                repaint();
                return;
            }
        }

        // 处理玩家移动的方法
        private void movePlayer() {
            // 如果游戏结束或暂停，不能移动
            if (gameOver || gamePaused) {
                return;
            }

            // 创建新的坐标变量，用于计算移动后的位置
            int dx = 0;
            int dy = 0;

            // 根据按键状态设置移动方向
            if (upPressed) {
                dy = -player.getSpeed();
                player.setImage(me1Img); // 向前移动时使用me1.png
            }
            if (downPressed) {
                dy = player.getSpeed();
                player.setImage(me1Img); // 向前移动时使用me1.png
            }
            if (leftPressed) {
                dx = -player.getSpeed();
                player.setImage(me2Img); // 左右移动时使用me2.png
            }
            if (rightPressed) {
                dx = player.getSpeed();
                player.setImage(me2Img); // 左右移动时使用me2.png
            }

            // 移动玩家
            player.move(dx, dy);

            // 如果没有移动（dx和dy都为0），设置为停止状态图片
            if (dx == 0 && dy == 0) {
                player.setImage(me2Img);
            }
        }

    // 移除了原来的movePlayer(KeyEvent e)方法，使用新的实现
    // 重写paintComponent方法绘制游戏画面
        @Override
        protected void paintComponent(Graphics g) {
            // 调用父类的paintComponent方法
            super.paintComponent(g);

            // 绘制背景图片，填满整个面板
            if (backgroundImg != null) {
                g.drawImage(backgroundImg, 0, 0, getWidth(), getHeight(), this);
            }

            // 绘制暂停按钮（在血条左边）
            int pauseButtonHeight = 0;
            if (pauseImg != null && !gameOver) {
                g.drawImage(pauseImg, 10, 10, this);
                pauseButtonHeight = pauseImg.getHeight(this);
            }

            // 绘制玩家血条背景(黑色边框)，在暂停按钮右边，高度与暂停按钮一致
            if (pauseButtonHeight > 0) {
                // 将血条位置向右移动20像素
                g.setColor(Color.BLACK);
                g.fillRect(65, 10, 154, pauseButtonHeight);

                // 绘制玩家血条(绿色)
                g.setColor(Color.GREEN);
                int healthWidth = (int) (150 * (player.getHealth() / (double)player.getMaxHealth()));
                g.fillRect(67, 12, healthWidth, pauseButtonHeight - 4);
            }

            // 绘制玩家飞机图片
            if (player.getImage() != null && (!gameOver || !showGameOverImage)) {
                g.drawImage(player.getImage(), player.getX(), player.getY(), this);
            }

            // 绘制所有敌机
            for (Enemy enemy : enemies) {
                if (enemy.getImage() != null && enemy.isAlive()) {
                    g.drawImage(enemy.getImage(), enemy.getX(), enemy.getY(), this);
                }
            }

            // 绘制所有敌机子弹
            for (Bullet bullet : enemyBullets) {
                if (bullet.getImage() != null && bullet.isAlive()) {
                    g.drawImage(bullet.getImage(), bullet.getX(), bullet.getY(), this);
                }
            }

            // 绘制所有玩家子弹
            for (Bullet bullet : playerBullets) {
                if (bullet.getImage() != null && bullet.isAlive()) {
                    g.drawImage(bullet.getImage(), bullet.getX(), bullet.getY(), this);
                }
            }

            // 绘制道具
            for (Prop prop : props) {
                if (prop.getImage() != null && prop.isAlive()) {
                    g.drawImage(prop.getImage(), prop.getX(), prop.getY(), this);
                }
            }

            // 绘制爆炸效果
            for (Explosion explosion : explosions) {
                Image img = explosion.getCurrentImage();
                if (img != null) {
                    g.drawImage(img, explosion.getX(), explosion.getY(), this);
                }
            }

            // 绘制分数和等级
            g.setColor(Color.WHITE);
            g.setFont(new Font("Arial", Font.BOLD, 16));
            g.drawString("分数: " + score, 10, getHeight() - 30);
            g.drawString("等级: " + level, 10, getHeight() - 10);

            // 如果游戏暂停，绘制恢复按钮
            if (gamePaused && resumeImg != null) {
                int resumeX = (getWidth() - resumeImg.getWidth(this)) / 2;
                int resumeY = (getHeight() - resumeImg.getHeight(this)) / 2;
                g.drawImage(resumeImg, resumeX, resumeY, this);
            }

            // 如果游戏结束，显示游戏结束信息
            if (gameOver && showGameOverImage && gameoverImg != null) {
                int imgWidth = gameoverImg.getWidth(this);
                int imgHeight = gameoverImg.getHeight(this);
                int x = (getWidth() - imgWidth) / 2;
                int y = (getHeight() - imgHeight) / 2;
                g.drawImage(gameoverImg, x, y, this);
            }

        }
    }
}